package com.ddxz.tool.core.common;

import com.ddxz.tool.core.convert.DateUtil;
import com.ddxz.tool.core.exception.DdxzTokenException;
import com.ddxz.tool.core.security.SecurityUtil;
import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.ddxz.tool.core.exception.DdxzErrorStatus.INVALID_TOKEN;

/**
 * class description
 *
 * @author 朱宗刚
 * @version 1.0.0
 * @date 2020/7/26
 */

public class DdxzJwtUtil {
    public DdxzJwtUtil() {
        validTime = 300000L;
    }

    public DdxzJwtUtil(long expired) {
        validTime = expired;
    }

    public String getToken(Map<String, Object> body) {
        return getToken(body, validTime);
    }

    public String getToken(Map<String, Object> body, long validMilliSecond) {
        body.forEach((key, val) -> body.replace(key, SecurityUtil.aes256Encode(val.toString())));
        return BEARER + Jwts.builder()
                .addClaims(body)
                .setHeader(header)
                .signWith(SignatureAlgorithm.HS512, key)
                .setExpiration(new Date(DateUtil.getTimestamp() + validMilliSecond))
                .compact();
    }

    public Map<String, Object> getBody(String token) {
        if(!token.startsWith(BEARER)) {
            throw new DdxzTokenException(INVALID_TOKEN);
        }

        try{
            Jwt jwt = Jwts.parser()
                    .setSigningKey(key)
                    .parse(token.substring(BEARER.length()));
            if(!COMPANY.equals(jwt.getHeader().get("cpy"))) {
                throw new DdxzTokenException(INVALID_TOKEN);
            }
            Map<String, Object> body = (Map<String, Object>) jwt.getBody();
            body.remove(EXP);
            body.forEach((key, val) -> body.replace(key, SecurityUtil.aes256Decode(val.toString())));

            return body;
        } catch (Exception e) {
            throw new DdxzTokenException(e, INVALID_TOKEN);
        }
    }

    private String key = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAO3fQBw7wJIB";

    private static final Map<String, Object> header = new HashMap<>(3);
    private static final String BEARER = "Bearer ";
    private static final String EXP = "exp";
    private static final String COMPANY = "ddxz";
    private long validTime;

    static {
        header.put("typ", "JWT");
        header.put("alg", "HS512");
        header.put("cpy", COMPANY);
    }
}
